﻿import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# 数据
X = 2*np.random.rand(100,1)
y = 4+3*X+np.random.randn(100,1)
# 增加一列，用于求解偏置项b
X_b = np.c_[(np.ones((100,1)), X)]

# 测试（直接求解得到的回归方程）
X_new = np.array([[0],[2]])
# 增加一列，偏置项b（同求解时一样）
X_new_b = np.c_[(np.ones((2,1)), X_new)]


def learning_schedule(t):
    return 5/(50+t)


theta_path_sgd = []
m = len(X_b)
n_epochs = 50
np.random.seed(0)
theta = np.random.randn(2,1)
for epoch in range(n_epochs):
    for i in range(m):
        if epoch < 10 and i < 10:
            y_predict = X_new_b.dot(theta)
            plt.plot(X_new,y_predict,'r-')
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2*xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch*m+i)
        theta = theta-eta*gradients
        theta_path_sgd.append(theta)

plt.plot(X,y,'b.')
plt.axis([0,2,0,15])
plt.show()